package com.ssrs.framework.i18n;

import com.ssrs.framework.extend.ExtendManager;
import com.ssrs.framework.point.I18nPoint;
import org.apache.commons.collections.MapUtils;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.support.AbstractMessageSource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;

import javax.annotation.PostConstruct;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 进行国际化扩展功能：读取扩展点国际化数据
 *
 * @author ssrs
 */
public class EightRoesMessageSource extends AbstractMessageSource implements ResourceLoaderAware {
    ResourceLoader resourceLoader;

    // 这个是用来缓存数据库中获取到的配置的 数据库配置更改的时候可以调用reload方法重新加载
    private static final Map<String, Map<String, String>> LOCAL_CACHE = new ConcurrentHashMap<>(256);


    /**
     * 重新将数据库中的国际化配置加载
     */
    public static void reload() {
        LOCAL_CACHE.clear();
        loadAllMessageResourcesFromDB();
    }

    /**
     * 从扩展行为中获取所有国际化配置
     */
    public static void loadAllMessageResourcesFromDB() {
        Object[] actionArray = ExtendManager.invoke(I18nPoint.ID, new Object[0]);
        for (Object action : actionArray) {
            LOCAL_CACHE.putAll((Map<String, Map<String, String>>) action);
        }
    }

    /**
     * 从缓存中取出国际化配置对应的数据 或者从父级获取
     *
     * @param code
     * @param locale
     * @return
     */
    public String getSourceFromCache(String code, Locale locale) {
        String language = locale.getLanguage();
        Map<String, String> props = LOCAL_CACHE.get(language);
        if (null != props && props.containsKey(code)) {
            return props.get(code);
        } else {
            try {
                if (null != this.getParentMessageSource()) {
                    return this.getParentMessageSource().getMessage(code, null, locale);
                }
            } catch (Exception ex) {
                logger.error(ex.getMessage(), ex);
            }
            return code;
        }
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = (resourceLoader == null ? new DefaultResourceLoader() : resourceLoader);
    }

    @Override
    protected MessageFormat resolveCode(String code, Locale locale) {
        String msg = getSourceFromCache(code, locale);
        return new MessageFormat(msg, locale);
    }

    @Override
    protected String resolveCodeWithoutArguments(String code, Locale locale) {
        return getSourceFromCache(code, locale);
    }

}
